package com.hzw.saas.api.storage;

import java.util.List;

import com.hzw.saas.api.storage.bo.ResourceFolderStructBO;
import com.hzw.saas.common.config.query.LogicQuery;
import com.hzw.saas.common.util.enums.AssertEnum;
import com.hzw.saas.common.util.enums.ConflictModeEnum;


/**
 * 资源目录服务接口
 *
 * @author zzl
 * @since 02/23/2021
 */
public interface IResourceFolderService {

    /**
     * 获取目录路径
     *
     * @param pid 目录ID
     * @return 目录路径, null-目录不存在
     */
    String getPathByPid(String pid);

    /**
     * 目录ID路径是否有效
     */
    boolean isValidPidPath(String pidPath);

    /**
     * 目录ID路径是否有效
     */
    boolean isValidPidPath(List<String> pidPath);

    /**
     * 获取目录路径
     *
     * @param pidPath 目录ID路径
     * @return 目录路径，null-ID路径中某目录不存在
     */
    String getPathByPidPath(String pidPath);

    /**
     * 获取目录路径
     *
     * @param pidPath 目录ID路径
     * @return 目录路径，null-ID路径中某目录不存在
     */
    String getPathByPidPath(List<String> pidPath);

    /**
     * 根据目录ID获取正常状态的目录信息
     *
     * @param pid        目录ID
     * @param assertEnum 结果检查, null或IGNORE-跳过结果检查
     * @return 目录信息
     */
    ResourceFolderStructBO getFolder(String pid, AssertEnum assertEnum);

    /**
     * 根据目录ID获取目录信息
     *
     * @param pid        目录ID
     * @param status     资源状态, 可为null
     * @param assertEnum 结果检查, null或IGNORE-跳过结果检查
     * @return 目录信息
     */
    ResourceFolderStructBO getFolder(String pid, LogicQuery<Integer> status, AssertEnum assertEnum);

    /**
     * 获取正常状态的目录列表
     *
     * @param pidList 目录ID列表
     * @return 目录列表
     */
    List<ResourceFolderStructBO> listFolders(List<String> pidList);

    /**
     * 获取指定状态的目录列表
     *
     * @param pidList 目录ID列表
     * @param status  指定状态，可为null
     * @return 目录列表
     */
    List<ResourceFolderStructBO> listFolders(List<String> pidList, LogicQuery<Integer> status);

    /**
     * 获取正常状态的子目录列表
     *
     * @param supId 父目录ID
     * @return 子目录列表
     */
    List<ResourceFolderStructBO> listSubFolders(String supId);

    /**
     * 获取子目录列表
     *
     * @param supId  父目录ID
     * @param status 资源状态, 可为null
     * @return 子目录列表
     */
    List<ResourceFolderStructBO> listSubFolders(String supId, LogicQuery<Integer> status);

    /**
     * @param supIdList
     * @return
     */
    List<ResourceFolderStructBO> listSubFolders(List<String> supIdList);

    /**
     * @param supIdList
     * @param status
     * @return
     */
    List<ResourceFolderStructBO> listSubFolders(List<String> supIdList, LogicQuery<Integer> status);

    /**
     * 获取存储空间内指定状态的目录列表
     *
     * @param userId  用户ID
     * @param spaceId 存储空间ID
     * @param status  资源状态, 可为null
     * @return 符合条件的目录列表
     */
    List<ResourceFolderStructBO> listUserFolders(String userId, String spaceId, LogicQuery<Integer> status);

    /**
     * 获取子目录ID列表
     *
     * @param supId  父目录ID
     * @param status 资源状态, 可为null
     * @return
     */
    List<String> listSubFolderPids(String supId, LogicQuery<Integer> status);

    /**
     * 获取子目录ID列表
     *
     * @param supIds  父目录ID
     * @param status 资源状态, 可为null
     * @return
     */
    List<String> listSubFolderPids(List<String> supIds, LogicQuery<Integer> status);

    /**
     * 检查目录下子目录名是否存在
     *
     * @param supId      父目录ID
     * @param folderName 目录名
     * @param status     资源状态, 可为null
     * @return true 存在, false 不存在
     */
    boolean isNameExist(String supId, String folderName, LogicQuery<Integer> status);

    /**
     * 计算目录大小
     *
     * @param pid       目录ID
     * @param status    资源状态, 可为null
     * @param integrity 文件完整性，null-不过滤
     * @return 目录大小, 单位: byte
     */
    long countSize(String pid, LogicQuery<Integer> status, LogicQuery<Integer> integrity);

    /**
     * 计算目录大小
     *
     * @param pidList   目录ID列表
     * @param status    资源状态, 可为null
     * @param integrity 文件完整性，null-不过滤
     * @return 目录大小, 单位: byte
     */
    long countSize(List<String> pidList, LogicQuery<Integer> status, LogicQuery<Integer> integrity);

    /**
     * 检查资是否属于用户
     *
     * @param userId   用户ID
     * @param folderId 目录ID
     * @return 结果 true/false
     */
    boolean checkAuthOwn(String userId, String folderId);

    /**
     * 检查资是否属于用户
     *
     * @param userId       用户ID
     * @param folderIdList 目录ID列表
     */
    boolean checkAuthOwn(String userId, List<String> folderIdList);

    /**
     * 检查资是否属于用户
     * 如果有不属于用户的目录则抛出异常
     *
     * @param userId       用户ID
     * @param folderIdList 目录ID列表
     */
    void assertAuthOwn(String userId, List<String> folderIdList);

    /**
     * 创建目录
     *
     * @param ResourceFolderBO 目录信息
     * @param conflictHandle   冲突模式
     * @return 目录信息，当不检查同名目录且同名目录存在时，返回该同名目录
     */
    ResourceFolderStructBO createFolder(ResourceFolderStructBO ResourceFolderBO, ConflictModeEnum conflictHandle);

    /**
     * 批次创建目录
     *
     * @param supId 父目录ID
     * @param path  待创建目录路径，支持多级创建
     * @return 目录路径中的目录信息列表，已存在的目录也会返回，如/user/image即返回user和image目录的信息，无论是新建还是已存在
     */
    List<ResourceFolderStructBO> createFoldersByPath(String supId, String path);

    /**
     * 复制目录
     *
     * @param srcPid         原目录ID
     * @param tarSupId       目标父目录ID
     * @param newName        新目录名，为空则使用原目录名
     * @param conflictHandle 目录名冲突解决方案
     */
    void copyFolder(String srcPid, String tarSupId, String newName, ConflictModeEnum conflictHandle);

    /**
     * 复制目录
     *
     * @param srcPidList     原目录ID列表
     * @param tarSupId       目标父目录ID
     * @param conflictHandle 目录名冲突解决方案
     */
    void copyFolders(List<String> srcPidList, String tarSupId, ConflictModeEnum conflictHandle);

    /**
     * 移动目录
     *
     * @param pid            原目录ID
     * @param tarSupId       目标父目录ID
     * @param newName        新目录名，为空则使用原目录名
     * @param conflictHandle 目录名冲突解决方案
     */
    void moveFolder(String pid, String tarSupId, String newName, ConflictModeEnum conflictHandle);

    /**
     * 移动目录
     *
     * @param pidList        目录列表
     * @param tarSupId       目标父目录
     * @param conflictHandle 目录名冲突解决方案
     */
    void moveFolders(List<String> pidList, String tarSupId, ConflictModeEnum conflictHandle);

    /**
     * 重命名目录
     *
     * @param pid            目录ID
     * @param newName        新名称
     * @param conflictHandle 目录名冲突解决方案
     */
    void renameFolder(String pid, String newName, ConflictModeEnum conflictHandle);

    /**
     * 回收目录
     *
     * @param pid 目录ID
     */
    void recycleFolder(String pid);

    /**
     * 批量回收目录
     *
     * @param pidList 目录ID
     */
    void recycleFolders(List<String> pidList);

    /**
     * 回收目录中的子目录
     * 为目录回收时，同时回收子目录使用
     *
     * @param supId 父目录ID
     */
    void recycleSubFolders(String supId);

    /**
     * 恢复目录
     *
     * @param pid      目录ID
     * @param tarSupId 恢复至的父目录ID，可选。为空时，恢复至目录原父目录
     */
    void restoreFolder(String pid, String tarSupId, String newName, ConflictModeEnum conflictHandle);

    /**
     * 批量恢复目录
     *
     * @param pidList  目录ID列表
     * @param tarSupId 恢复至的父目录ID，可选。为空时，恢复至目录原父目录
     */
    void restoreFolders(List<String> pidList, String tarSupId, ConflictModeEnum conflictHandle);

    /**
     * 恢复目录中的子目录
     * 一般为恢复目录时同时恢复子目录操作
     *
     * @param supId    父目录ID
     * @param tarSupId 恢复至的父目录ID，可选。为空时，恢复至目录原父目录
     */
    void restoreSubFolders(String supId, String tarSupId, ConflictModeEnum conflictHandle);

    /**
     * 删除目录
     *
     * @param pid 目录ID
     */
    void deleteFolder(String pid);

    /**
     * 批量删除目录
     *
     * @param pidList 目录ID
     */
    void deleteFolders(List<String> pidList);

    /**
     * 删除目录中的子目录
     * 为目录删除时，同时删除子目录使用
     *
     * @param supId 父目录ID
     */
    void deleteSubFolder(String supId);

    /**
     * 复活目录
     * 将已被删除的目录复活
     * 一般在文件版本中使用，复活低版本目录
     *
     * @param pid      目录ID
     * @param tarSupId 恢复至的父目录ID，可选。为空时，恢复至目录原父目录
     */
    void resurrectFolder(String pid, String tarSupId, String newName, ConflictModeEnum conflictHandle);

    /**
     * 批量复活目录
     * 将已被删除的目录复活
     * 一般在文件版本中使用，复活低版本目录
     *
     * @param pidList  目录ID列表
     * @param tarSupId 恢复至的父目录ID，可选。为空时，恢复至目录原父目录
     */
    void resurrectFolders(List<String> pidList, String tarSupId, ConflictModeEnum conflictHandle);

}
